package org.example.threadlocaltest.demos.configure;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    //这里一旦有这个类，就会覆盖掉默认的 security 配置，也就拿不到 默认的过滤器链了
    //即便在这个配置累里面什么也不写

    @Autowired
    private MyOnceFilter myOnceFilter;

    @Bean//使用 BCryptPasswordEncoder 对密码进行加密
    public BCryptPasswordEncoder bcryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    @Override //放行 /public/login 接口
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//不使用 session
        http.authorizeRequests()
                .antMatchers("/public/login").permitAll() //放行 /public/login 接口 注意 这里是 permitAll() 不是
                                                            // anonymous()，permitAll() 是匿名/不匿名都可以访问，而 anonymous()
                                                            // 是只能匿名访问，所以具体采用哪个要根据实际情况来定
                //另外，这里的 permitAll() 意思是，当你访问 /public/login 接口时，经过 FilterSecurityInterceptor 这个过滤器的时候
                //FilterSecurityInterceptor 不会对你进行认证，直接放行，而不是让你直接跳过所有的过滤器，实际上
                //你一个过滤器都跳不过去，只不过 FilterSecurityInterceptor 这个过滤器不会对你进行认证，其他的过滤器内部逻辑
                //该怎么执行还是会怎么执行。
                .antMatchers("/druid/**").permitAll()      //放行 druid 监控页面
                .anyRequest().authenticated()               //其他接口都需要认证
                .and()
                .csrf().disable();                          //因为现在都是前后端分离的，所以 csrf 就不需要了

        //这里的配置是为了让我们自己的过滤器生效
        http.addFilterBefore(myOnceFilter, UsernamePasswordAuthenticationFilter.class);

    }
}
